﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KlubSportowy.Repositories.Memory;
using KlubSportowy.Controllers;
using System.Data.Objects;
using System.Web.Mvc;
using System.Web.Security;

namespace KlubSportowy.Repositories
{
    class MemoryContributionsRepository : IContributionsRepository
    {
        private readonly MemoryDataSource _dataSource;

        public MemoryContributionsRepository(MemoryDataSource dataSource)
        {
            _dataSource = dataSource;
        }

        public List<UsersContributions> GetAllContributions()
        {
            return _dataSource.Contributions.OrderBy(c => c.ContributionDate).ToList();
        }

        public List<UsersContributions> GetContributions(int startIndex, int count, string sorting)
        {
            Guid userGuid = (Guid)Membership.GetUser().ProviderUserKey;
            IEnumerable<UsersContributions> query;
            if (Roles.IsUserInRole("Administratorzy"))
            {
                query = _dataSource.Contributions;
            }
            else
            {
                query = _dataSource.Contributions.Where(x => x.UserId == userGuid);
            }

            //Sorting
            //This ugly code is used just for demonstration.
            //Normally, Incoming sorting text can be directly appended to an SQL query.
            if (string.IsNullOrEmpty(sorting) || sorting.Equals("UserName ASC"))
            {
                query = query.OrderBy(p => p.UserName);
            }
            else if (sorting.Equals("UserName DESC"))
            {
                query = query.OrderByDescending(p => p.UserName);
            }
            else if (sorting.Equals("UserId ASC"))
            {
                query = query.OrderBy(p => p.UserId);
            }
            else if (sorting.Equals("UserId DESC"))
            {
                query = query.OrderByDescending(p => p.UserId);
            }
            else if (sorting.Equals("AmountId ASC"))
            {
                query = query.OrderBy(p => p.AmountId);
            }
            else if (sorting.Equals("AmountId DESC"))
            {
                query = query.OrderByDescending(p => p.AmountId);
            }
            else
            {
                query = query.OrderBy(p => p.UserName); //Default!
            }

            return count > 0
                       ? query.Skip(startIndex).Take(count).ToList()
                       : query.ToList(); 
        }

        public int GetContributionsCount()
        {
            return _dataSource.Contributions.Count;
        }

        public int GetContributionsCountByFilter(string Name, int UserId)
        {
            return _dataSource.Contributions.Where(c => c.UserId == RepositorySession.IntToGuid(UserId)).Count();
        }

        public List<UsersContributions> GetContributionsByFilter(string name, int UserId, int startIndex, int count, string sorting)
        {
            IEnumerable<UsersContributions> query = _dataSource.Contributions;

            //Filters
            if (!string.IsNullOrEmpty(name))
            {
                query = query.Where(p => p.UserName.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0);
            }

            if (UserId > 0)
            {
                query = query.Where(p => p.UserId ==  RepositorySession.IntToGuid(UserId));
            }

            //Sorting
            //This ugly code is used just for demonstration.
            //Normally, Incoming sorting text can be directly appended to an SQL query.
            if (string.IsNullOrEmpty(sorting) || sorting.Equals("UserName ASC"))
            {
                query = query.OrderBy(p => p.UserName);
            }
            else if (sorting.Equals("UserName DESC"))
            {
                query = query.OrderByDescending(p => p.UserName);
            }
            else if (sorting.Equals("UserId ASC"))
            {
                query = query.OrderBy(p => p.UserId);
            }
            else if (sorting.Equals("UserId DESC"))
            {
                query = query.OrderByDescending(p => p.UserId);
            }
            else if (sorting.Equals("AmountId ASC"))
            {
                query = query.OrderBy(p => p.AmountId);
            }
            else if (sorting.Equals("AmountId DESC"))
            {
                query = query.OrderByDescending(p => p.AmountId);
            }
            else
            {
                query = query.OrderBy(p => p.UserName); //Default!
            }

            return count > 0
                       ? query.Skip(startIndex).Take(count).ToList() 
                       : query.ToList(); 
        }

        public UsersContributions AddContribution(UsersContributions contribution)
        {
            dbEntities db = new dbEntities();
            ContributionsOfUser cou = new ContributionsOfUser();
            cou.Id = db.ContributionsOfUser.Max(x => x.Id) + 1;
            cou.UserId = contribution.UserId;
            cou.ContributionId = contribution.AmountId;
            cou.State = contribution.State;
            db.ContributionsOfUser.AddObject(cou);
            db.SaveChanges();
            contribution.PaymentDate = cou.ContributionsSet.PaymentDate;
            contribution.Amount = cou.ContributionsSet.Amount;
            contribution.COUId = cou.Id;
            contribution.AmountId = cou.ContributionsSet.Id;
            contribution.Description = cou.ContributionsSet.Description;
            contribution.State = cou.State.Value;
            contribution.UserId = cou.aspnet_Users.UserId;
            contribution.UserName = cou.aspnet_Users.UserName;
            _dataSource.Contributions.Add(contribution);
            return contribution;
        }

        public void DeleteContribution(int COUId)
        {
            dbEntities db = new dbEntities();
            db.ContributionsOfUser.DeleteObject( db.ContributionsOfUser.Where(c => c.Id == COUId).First());
            db.SaveChanges();
            _dataSource.Contributions.RemoveAll(s => s.COUId == COUId);
        }

        public void UpdateContribution(UsersContributions contribution)
        {

            var foundContribution = _dataSource.Contributions.FirstOrDefault(s => s.COUId == contribution.COUId);
            if (foundContribution == null)
            {
                return;
            }

            foundContribution.AmountId = contribution.AmountId;
            foundContribution.UserId = contribution.UserId;
            foundContribution.State = contribution.State;
            dbEntities db = new dbEntities();
            ContributionsOfUser c = db.ContributionsOfUser.Where(co => co.Id == contribution.COUId).First();
            c.UserId = contribution.UserId;
            c.ContributionId = contribution.AmountId;
            c.State = contribution.State;
            db.SaveChanges();
        
        }

        public IContributionsRepository ContributionsRepository
        {
            get { return new MemoryContributionsRepository(_dataSource); }
        }
    }
}
